package com.huitone.gddw.controller.monitoring.environment.host;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.huitone.gddw.common.ComConstant;
import com.huitone.gddw.dao.entity.ObjectDef;
import com.huitone.gddw.log.Log;
import com.huitone.gddw.log.LogResult;
import com.huitone.gddw.log.LogType;
import com.huitone.gddw.service.dto.monitoring.UnifyMonitorDTO;
import com.huitone.gddw.service.dto.monitoring.environment.EnvDTO;
import com.huitone.gddw.service.monitoring.base.IObjectDefService;
import com.huitone.gddw.service.monitoring.environment.host.ISystemMonitorService;

/**
 * 系统监控
 * @author wuluodan
 *
 */
@Controller
@RequestMapping(value="systemMon")
public class SystemMonitorController {

	private final static Logger LOGGER = Logger.getLogger(SystemMonitorController.class);
	
	@Autowired
	private ISystemMonitorService systemMonitorService;
	
	@Autowired
	private IObjectDefService objectDefService;
	
	/**
	 * 查询所有主机
	 * @param request
	 * @return List<ObjectDef>
	 */
	@ResponseBody
	@RequestMapping(value="findHost")
	@Log(logType=LogType.SELECT, content="系统监控-查询主机系统监控信息")
	public List<ObjectDef> findHost(HttpServletRequest request) {
		try {
			return objectDefService.getByObjType(ComConstant.HOST);
		} catch (Exception e) {
			LOGGER.error("查询所有主机信息出现异常：" + e.getMessage(), e);
			request.setAttribute("logResult", LogResult.EXCEPTION);
			return null;
		}
	}
	
	/**
	 * 查询主机系统信息
	 * @param objId 主机ID
	 * @param request
	 * @return List<EnvDTO>
	 */
	@ResponseBody
	@RequestMapping(value="findHostBasic")
	public Map<String, Object> findHostBasic(String objId, HttpServletRequest request) {
		try {
			List<EnvDTO> list = systemMonitorService.findHostBasic(objId);
			
			Map<String, Object> result = new HashMap<>();
			for (EnvDTO envDTO : list) {
				result.put(envDTO.getKey(), envDTO);
			}
			
			return result;
		} catch (Exception e) {
			LOGGER.error("查询主机系统信息出现异常：" + e.getMessage(), e);
			return null;
		}
	}
	
	/**
	 * 查询主机硬件信息
	 * @param objId 主机ID
	 * @param request
	 * @return Map<String, Object>
	 */
	@SuppressWarnings("unchecked")
	@ResponseBody
	@RequestMapping(value="findHostHardware")
	public Map<String, Object> findHostHardware(String objId, HttpServletRequest request) {
		try {
			List<EnvDTO> result = systemMonitorService.findHostHardware(objId);
			
			Map<String, Object> map = new HashMap<>();
			for (EnvDTO envDTO : result) {
				if (envDTO.getApplications() != null) {
					if (map.containsKey(envDTO.getApplications())) {
						Map<String, Object> mapSeq = (Map<String, Object>)map.get(envDTO.getApplications());
						if (mapSeq.containsKey(envDTO.getSeq().toString())) {
							Map<String, Object> mapObj = (Map<String, Object>)mapSeq.get(envDTO.getSeq().toString());
							mapObj.put(envDTO.getKey(), envDTO);
						} else {
							Map<String, Object> mapObj = new HashMap<>();
							mapObj.put(envDTO.getKey(), envDTO);
							mapSeq.put(envDTO.getSeq().toString(), mapObj);
						}
					} else {
						Map<String, Object> mapObj = new HashMap<>();
						mapObj.put(envDTO.getKey(), envDTO);
						Map<String, Object> mapSeq = new HashMap<>();
						mapSeq.put(envDTO.getSeq().toString(), mapObj);
						map.put(envDTO.getApplications(), mapSeq);
					}
				} else {
					map.put(envDTO.getKey(), envDTO);
				}
			}
			
			return map;
		} catch (Exception e) {
			LOGGER.error("查询主机硬件信息出现异常：" + e.getMessage(), e);
			return null;
		}
	}
	
	/**
	 * 查询主机任务信息
	 * @param objId 主机ID
	 * @param request
	 * @return Map<String, Object>
	 */
	@ResponseBody
	@RequestMapping(value="findHostTask")
	public Map<String, Object> findHostTask(String objId, HttpServletRequest request) {
		try {
			List<EnvDTO> list = systemMonitorService.findHostTask(objId);
			
			Map<String, Object> result = new HashMap<>();
			for (EnvDTO envDTO : list) {
				result.put(envDTO.getKey(), envDTO);
			}
			
			return result;
		} catch (Exception e) {
			LOGGER.error("查询主机任务信息出现异常：" + e.getMessage(), e);
			return null;
		}
	}
	
	/**
	 * 查询主机资源使用信息
	 * @param objId 主机ID
	 * @param request
	 * @return List<Map<String, Object>>
	 */
	@SuppressWarnings("unchecked")
	@ResponseBody
	@RequestMapping(value="findHostRecuse")
	public Map<String, Object> findHostRecuse(String objId, HttpServletRequest request) {
		try {
			int startDate = Integer.parseInt(request.getParameter("startDate"));
			int endDate = Integer.parseInt(request.getParameter("endDate"));
			int interval = Integer.parseInt(request.getParameter("interval"));
			Map<String, Object> params = new HashMap<>();
			params.put("startDate", startDate - interval);
			params.put("endDate", endDate);
			params.put("interval", interval);
			params.put("objId", objId);
			List<EnvDTO> result = systemMonitorService.findHostRecuse(params);
			
			Map<String, Object> map = new HashMap<>();
			for (EnvDTO envDTO : result) {
				// 判断是否为磁盘信息
				if (envDTO.getApplications() != null && envDTO.getApplications().equals(ComConstant.HDISK)) {
					// 判断是否已存储磁盘信息
					if (map.get(envDTO.getApplications()) != null) {
						Map<String, Object> mapSeq = (Map<String, Object>)map.get(envDTO.getApplications());
						// 判断是否已存储该磁盘
						if (mapSeq.containsKey(envDTO.getSeq().toString())) {
							Map<String, Object> mapObj = (Map<String, Object>)mapSeq.get(envDTO.getSeq().toString());
							// 判断该磁盘key是否已存在并且为磁盘使用率
							if (mapObj.containsKey(envDTO.getKey()) && envDTO.getKey().equals(ComConstant.HDISKUSE)) {
								List<EnvDTO> listEnv = (List<EnvDTO>)mapObj.get(envDTO.getKey());
								listEnv.add(envDTO);
							} else { // 否，添加或更新磁盘属性
								if (envDTO.getKey().equals(ComConstant.HDISKUSE)) {
									List<EnvDTO> listEnv = new ArrayList<>();
									listEnv.add(envDTO);
									mapObj.put(envDTO.getKey(), listEnv);
								} else {
									mapObj.put(envDTO.getKey(), envDTO);
								}
							}
						} else { // 否，添加seq-diskname/diskuse-dto/list
							Map<String, Object> mapObj = new HashMap<>();
							if (envDTO.getKey().equals(ComConstant.HDISKUSE)) {
								List<EnvDTO> listEnv = new ArrayList<>();
								listEnv.add(envDTO);
								mapObj.put(envDTO.getKey(), listEnv);
							} else {
								mapObj.put(envDTO.getKey(), envDTO);
							}
							mapSeq.put(envDTO.getSeq().toString(), mapObj);
						}
					} else { // 不存在，添加applications-seq-diskname/diskuse-dto/list
						Map<String, Object> mapObj = new HashMap<>();
						if (envDTO.getKey().equals(ComConstant.HDISKUSE)) {
							List<EnvDTO> listEnv = new ArrayList<>();
							listEnv.add(envDTO);
							mapObj.put(envDTO.getKey(), listEnv);
						} else {
							mapObj.put(envDTO.getKey(), envDTO);
						}
						Map<String, Object> mapSeq = new HashMap<>();
						mapSeq.put(envDTO.getSeq().toString(), mapObj);
						map.put(envDTO.getApplications(), mapSeq);
					}
				} else {
					if (map.containsKey(envDTO.getKey())) {
						List<EnvDTO> l = (List<EnvDTO>)map.get(envDTO.getKey());
						l.add(envDTO);
					} else {
						List<EnvDTO> listEnv = new ArrayList<>();
						listEnv.add(envDTO);
						map.put(envDTO.getKey(), listEnv);
					}
				}
				
			}
			
			// 再次封装磁盘数据，格式为 sda:value1,value2...
			if (map.containsKey(ComConstant.HDISK)) {
				Map<String, Object> mapHdisk = (Map<String, Object>)map.get(ComConstant.HDISK);
				Map<String, Object> mapTemp = new HashMap<>();
				for (Map.Entry<String, Object> entSeq : mapHdisk.entrySet()) {
					Map<String, Object> mapSeq = (Map<String, Object>)entSeq.getValue();
					EnvDTO envDTO = (EnvDTO)mapSeq.get(ComConstant.HDISKNAME);
					List<EnvDTO> list = (List<EnvDTO>)mapSeq.get(ComConstant.HDISKUSE);
					List<String> listValue = new ArrayList<>();
					for (EnvDTO obj : (list == null ? new ArrayList<EnvDTO>() : list)) {
						listValue.add(obj.getValue());
					}
					mapTemp.put(envDTO.getValue(), listValue);
				}
				mapHdisk.clear();
				mapHdisk.putAll(mapTemp);
			}
			
			List<String> listKey = new ArrayList<>();
			listKey.addAll(ComConstant.RECUSE_CPU);
			listKey.addAll(ComConstant.RECUSE_MEM);
			listKey.addAll(ComConstant.RECUSE_NET);
			listKey.addAll(ComConstant.RECUSE_CPULOAD);
			for (String key : listKey) {
				if (map.containsKey(key)) {
					List<EnvDTO> re = (List<EnvDTO>)map.get(key);
					int stime = startDate - interval;
					int etime = stime + interval;
					int j = 0;
					List<EnvDTO> list = new ArrayList<>();
					while (etime <= endDate) {
						float data = 0.0f;
						if (j > 0) {
							stime = etime;
							etime = stime + interval;
						}
						int i = 0;
						EnvDTO env = new EnvDTO();
						Iterator<EnvDTO> it = re.iterator();
						boolean b = false;
						while (it.hasNext()) {
							env = it.next();
							if (env.getClock() != null && env.getClock() > stime && env.getClock() <= etime) {
								if (0 == i) {
									list.add(env);
									b = true;
								}
								String v = env.getValue();
								if (v.startsWith(".")) {
									v = "0" + v;
								}
								data += Float.parseFloat(v);
								it.remove();
								i++;
							}
						}
						if (!b) {
							EnvDTO e = new EnvDTO();
							e.setValue("");
							e.setClock(etime);
							e.setClockTime(new Date((long)(etime) * 1000));
							e.setKey(key);
							list.add(e);
						} else if (list != null && list.size() > 0 && b) {
							if (!ComConstant.RECUSE_NET.contains(key)) {
								data = data / i;
							}
							list.get(list.size() - 1).setValue(String.valueOf(Math.floor(data)));
							list.get(list.size() - 1).setClockTime(new Date((long)(etime) * 1000));
						}
						j++;
					}
					map.put(key, list);
				}
			}
			
			// 这里将map.entrySet()转换成list
//	        List<Map.Entry<String, Object>> list = new ArrayList<Map.Entry<String, Object>>(map.entrySet());
//	        // 然后通过比较器来实现排序
//	        Collections.sort(list, new Comparator<Map.Entry<String, Object>>() {
//	            // 升序排序
//	            public int compare(Entry<String, Object> o1, Entry<String, Object> o2) {
//	            	EnvDTO e1 = (EnvDTO)o1.getValue();
//	            	EnvDTO e2 = (EnvDTO)o2.getValue();
//	            	return e1.getClock() - e2.getClock();
//	            }
//	            
//	        });
			
//			for (Entry<String, Object> entry : map.entrySet()) {
//				System.out.println(entry.getKey() + ":" + entry.getValue());
//				List<EnvDTO> l = (List<EnvDTO>)entry.getValue();
//				System.out.println(l);
//			}
			
			return map;
		} catch (Exception e) {
			LOGGER.error("查询主机资源使用信息出现异常：" + e.getMessage(), e);
			return null;
		}
	}
	
	/**
	 * 查询主机进程使用资源信息
	 * @param objId 主机ID
	 * @param request
	 * @return List<EnvDTO>
	 */
	@ResponseBody
	@RequestMapping(value="findHostPid")
	public List<Map<String, Object>> findHostPid(String objId, HttpServletRequest request) {
		try {
			List<EnvDTO> result = systemMonitorService.findHostPid(objId);
			
			List<Map<String, Object>> all = new ArrayList<>();
			for (EnvDTO envDTO : result) {
				boolean isSame = false;
				for (Map<String, Object> map : all) {
					if (map.get("seq").toString().equals(envDTO.getSeq().toString())) {
						map.put(envDTO.getKey(), envDTO.getValue());
						isSame = true;
						break;
					}
				}
				if (!isSame) {
					Map<String, Object> map = new HashMap<>();
					map.put("seq", envDTO.getSeq());
					map.put(envDTO.getKey(), envDTO.getValue());
					all.add(map);
				}
			}
			
			return all;
		} catch (Exception e) {
			LOGGER.error("查询主机进程使用资源信息出现异常：" + e.getMessage(), e);
			return null;
		}
	}
	
}
